package com.chenfan.mcn.model.rpc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 财务回调基类
 *
 * @author wulg
 * @date 2022-07-28
 **/
@Data
@JSONType(typeKey="sceneCode",
        autoTypeCheckHandler = AbstractFinanceCallback.CallbackAutoTypeCheckHandler.class,
        seeAlso = {
                ChangeAnnualRebateStatusCallback.class,
                InvoicedCallback.class,
                BatchInvoicedCallback.class,
                ChargeClearCallback.class,
                BatchChargeClearCallback.class,
                ExcutionOrderChangePaidCallback.class,
                ExcutionOrderPaidCallback.class
        })
public abstract class AbstractFinanceCallback implements BusinessScene, Serializable {

    private static final long serialVersionUID = 2845244581167335495L;

    /**
     * 操作人ID
     */
    @NotNull(message = "操作人ID不能为空")
    private Long operatorId;

    /**
     * 操作人名称
     */
    @NotBlank(message = "操作人名称不能为空")
    private String operatorName;

    /**
     * 操作日期
     */
    @NotNull(message = "操作日期不能为空")
    private Date operateDate;

    /**
     * 租户ID
     */
    private Long tenantId;

    /**
     * 多态检查处理
     */
    public static class CallbackAutoTypeCheckHandler implements ParserConfig.AutoTypeCheckHandler {

        private static Map<String, Class<?>> typeMap = new ConcurrentHashMap<>();

        static {
            JSONType parentJsonType = AbstractFinanceCallback.class.getAnnotation(JSONType.class);
            Class<?>[] seeAlso = parentJsonType.seeAlso();
            for(Class<?> clazz : seeAlso){
                JSONType subJsonType = clazz.getAnnotation(JSONType.class);
                typeMap.putIfAbsent(subJsonType.typeName(), clazz);
            }
        }

        @Override
        public Class<?> handler(String typeName, Class<?> expectClass, int features) {
            if(!typeMap.containsKey(typeName)) {
                return IllegalFinanceCallback.class;
            }
            return typeMap.get(typeName);
        }
    }

//    public static void main(String[] args) {
//        ChargeClearCallback message = new ChargeClearCallback();
//        message.setTenantId(1L);
//        message.setClearNo("123");
//        String msgJson2 = JSON.toJSONString(message, SerializerFeature.WriteClassName);
//        Object object = JSON.parseObject(msgJson2, AbstractFinanceCallback.class);
//        System.out.println(object);
//    }
}
